// 类型定义和上下文创建
import type { FC, PropsWithChildren } from 'react';

import { useMount } from 'ahooks';
import { ThemeMode, type ThemeModeType } from 'ahooks/lib/useTheme';

import { localStg } from '@/utils/storage';

import { ThemeContext, toggleCssDarkMode } from './themeContext';

/**
 * 暗色模式媒体查询字符串
 * @constant {string}
 */
const DARK_MODE_MEDIA_QUERY = '(prefers-color-scheme: dark)';

/**
 * ThemeProvider 组件
 * 提供应用程序的主题上下文，管理主题模式切换和系统主题偏好监听
 *
 * @component
 * @param {PropsWithChildren} props - 组件属性
 * @property {ReactNode} children - 子组件
 * @returns {JSX.Element} 包含主题上下文的组件
 *
 * @example
 * // 基本用法
 * <ThemeProvider>
 *   <App />
 * </ThemeProvider>
 */
const ThemeProvider: FC<PropsWithChildren> = ({ children }) => {
	/**
	 * 主题模式状态
	 * @state {ThemeModeType}
	 * @default 'light'
	 */
	const [themeMode, setThemeMode] = useState<ThemeModeType>(
		(localStg.get('themeMode') as ThemeModeType) || 'light'
	);

	/**
	 * 当前是否为暗模式
	 * @type {boolean}
	 */
	const darkMode = themeMode === 'dark';

	/**
	 * 更改主题模式
	 * @function
	 * @param {ThemeModeType} mode - 要设置的主题模式
	 * @description 更新主题状态并持久化到本地存储
	 */
	function changeThemeMode(mode: ThemeModeType) {
		setThemeMode(mode);
		localStg.set('themeMode', mode); // 持久化主题模式到本地存储
	}

	/**
	 * 切换主题方案
	 * @function
	 * @description 循环切换主题模式 (light → dark → system → light)
	 */
	const toggleThemeScheme = () => {
		const themeModes = Object.values(ThemeMode);
		const index = themeModes.findIndex(item => item === themeMode);
		const nextIndex = index === themeModes.length - 1 ? 0 : index + 1; // 循环索引
		changeThemeMode(themeModes[nextIndex]);
	};

	// 监听暗模式变化
	useEffect(() => {
		toggleCssDarkMode(darkMode); // 切换CSS类
		localStg.set('darkMode', darkMode); // 持久化暗模式状态
	}, [darkMode]);

	// 初始化系统主题监听
	useMount(() => {
		const mediaQuery = window.matchMedia(DARK_MODE_MEDIA_QUERY);

		/**
		 * 系统主题变化处理器
		 * @param {MediaQueryListEvent} event - 媒体查询事件
		 */
		const handler = (event: MediaQueryListEvent) => {
			// 仅在系统主题模式下响应
			if (themeMode !== 'system') return;
			changeThemeMode(event.matches ? 'dark' : 'light');
		};

		// 添加监听器
		mediaQuery.addEventListener('change', handler);

		// 清理函数
		return () => {
			mediaQuery.removeEventListener('change', handler);
		};
	});

	return (
		<ThemeContext
			value={{
				darkMode, // 当前是否为暗模式
				setThemeScheme: changeThemeMode, // 设置主题方法
				themeScheme: themeMode, // 当前主题模式
				toggleThemeScheme // 切换主题方法
			}}
		>
			{children}
		</ThemeContext>
	);
};

export default ThemeProvider;

// 示例用法
/**
 * 示例：如何使用 ThemeProvider 组件
 *
 * ```jsx
 * import React from 'react';
 * import ThemeProvider from './ThemeProvider';
 *
 * const App = () => (
 *   <ThemeProvider>
 *     <div>应用内容</div>
 *   </ThemeProvider>
 * );
 *
 * export default App;
 * ```
 */
